/*
 * Copyright 2010 Eligio Colutta
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at 
 * http://www.apache.org/licenses/LICENSE-2.0 
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 * See the License for the specific language governing permissions and 
 * limitations under the License. 
 */
package com.google.code.p2pxmppclient.notifyserver;

import java.io.IOException;
import java.net.Inet4Address;
import java.net.ServerSocket;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.packet.Message;

import com.google.code.p2pxmppclient.Configurer;
import com.google.code.p2pxmppclient.XMPPRosterListener;

/**
 * 
 * @author eliosh
 * @version $Rev$
 * @lastautorcommit $Author$
 * @lastdatecommit $Date$
 */
@SuppressWarnings("unchecked")
public final class NotifyServer {
	private XMPPConnection conn;
	private static Map<String, List<OfflineMessage>> offlineMessages= Collections.synchronizedMap(new HashMap());
	private static final Logger log = Logger.getLogger(NotifyServer.class.getCanonicalName());
	
	public NotifyServer(XMPPConnection connection){
		this.conn = connection;
		conn.getRoster().addRosterListener(new XMPPRosterListener(this, conn));
	}
	
	public void startServer() throws IOException{
        ServerSocket serverSocket = null;
        boolean listening = true;
        int port = Configurer.getServer_port();
        try {
            serverSocket = new ServerSocket(port, 50, Inet4Address.getByName("localhost"));
            log.info("Server is listening on port " + port);
        } catch (IOException e) {
            log.severe("Could not listen on port: " + port);
            System.exit(-1);
        }

        while (listening){
        	new NotifyServerThread(conn, serverSocket.accept()).start();
        }
        serverSocket.close();
	}

	public static void addOfflineNotification(String recipient, String message){
		if(offlineMessages.containsKey(recipient)){
			List<OfflineMessage> list = offlineMessages.get(recipient);
			list.add(new OfflineMessage(message));
		}else{
			List<OfflineMessage> list = new ArrayList<OfflineMessage>(); // offlineMessages.get(recipient);
			list.add(new OfflineMessage(message));
			offlineMessages.put(recipient, list);
		}
	}
	
	public static void removeNotificationForUser(String recipient){
		if(offlineMessages.containsKey(recipient)){
			offlineMessages.remove(recipient);
		}
	}
	
	public void returnToAvailable(String recipient){
		if(offlineMessages.containsKey(recipient)){
			List<OfflineMessage> list = offlineMessages.get(recipient);
			log.info("Try to send " + list.size() + " message(s) to " + recipient);
			StringBuilder sb = new StringBuilder();
			sb.append("\n");
			for(OfflineMessage om : list){
				sb.append(om.toString()).append("\n");
			}
			Message reply = new Message();
			reply.setTo(recipient);
			reply.setBody(sb.toString());
			conn.sendPacket(reply);
			log.info("Offline messages sent to " + recipient);
			removeNotificationForUser(recipient);
		} else {
			log.info("No offline messages for " + recipient);
		}
	}
}
